#include "im.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>


char *StrUpper(char *s)
{
  int i, len = strlen(s);
  
  for (i = 0; i < len; i++) 
    s[i] = toupper(s[i]);
  
  return s;
}


void Usage(void)
{
  printf("Quantize <input file> <output file> <output format> /C\n");
  printf("   Converts a RGB True Color (24 bits) image into\n");
  printf("            a 256 colors palette based image.\n");
  printf("<input file> - RGB True Color (24 bits) Image File Name\n");
  printf("<output file> - 256 Palette Based Colors Image File Name\n");
  printf("<output format> - Valid options:\n");
  printf("                                 /BMP\n");
  printf("                                 /PCX\n");
  printf("                                 /GIF\n");
  printf("                                 /TIF\n");
  printf("                                 /RAS\n");
  printf("                                 /SGI\n");
  printf("                                 /TGA\n");
  printf("                                 /LED\n");
  printf("                                 /JPG\n");
  printf("/C - Compress on output.\n");
}

int CheckParam(char* Param, const char* Value)
{
  if (Param[0] != '/')
    return 0;
  
  Param++;
  
  if (strstr(StrUpper(Param), Value) == NULL)
    return 0;
  
  return 1;
}

void ErrorMsg(const char* Func, int err)
{
  char Text[256];
  strcpy(Text, Func);
  strcat(Text, " - ");
  
  switch (err)
  {
  case IM_ERR_OPEN:
    strcat(Text, "Error Opening File.\n");
    break;
  case IM_ERR_READ:
    strcat(Text, "Error Reading File.\n");
    break;
  case IM_ERR_WRITE:
    strcat(Text, "Error Writing File.\n");
    break;
  case IM_ERR_TYPE:
    strcat(Text, "Image not Suported.\n");
    break;
  case IM_ERR_FORMAT:
    strcat(Text, "Invalid Format.\n");
    break;
  case IM_ERR_COMP:
    strcat(Text, "Compression not suported.\n");
    break;
  default:
    strcat(Text, "Unknown Error.\n");
  }
  
  printf(Text);
}

int main(int NumParam, char* ParamStr[])
{
  int w,h,t,f,err,pal_size;
  unsigned char *red, *green, *blue, *map;
  long size, *color;
  
  if (NumParam < 2 || ParamStr[1][0] == '?' || NumParam < 4)
  {
    Usage();
    return 0;
  }
  
  if (CheckParam(ParamStr[3], "BMP"))
    f = IM_BMP;
  else if (CheckParam(ParamStr[3], "PCX"))
    f = IM_PCX;
  else if (CheckParam(ParamStr[3], "GIF"))
    f = IM_GIF;
  else if (CheckParam(ParamStr[3], "TIF"))
    f = IM_TIF;
  else if (CheckParam(ParamStr[3], "RAS"))
    f = IM_RAS;
  else if (CheckParam(ParamStr[3], "SGI"))
    f = IM_SGI;
  else if (CheckParam(ParamStr[3], "TGA"))
    f = IM_TGA;
  else if (CheckParam(ParamStr[3], "LED"))
    f = IM_LED;
  else if (CheckParam(ParamStr[3], "JPG"))
    f = IM_JPG;
  else
  {
    printf("Invalid Format Parameter.\n");
    return 0;
  }
  
  if (NumParam == 5 && CheckParam(ParamStr[4], "C"))
    f |= IM_DEFAULT;
  
  printf("ImQuantize %s\n", ParamStr[1]);
  
  err = imImageInfo(ParamStr[1], &w, &h, &t, &pal_size);
  
  if (err)
  {
    ErrorMsg("Image Info", err);
    return 0;
  }
  
  if (t != 0)
  {
    printf("Input Image not a RGB True Color (24 bits) Image.\n");
    return 0;
  }
  
  size = (long)w * (long)h;
  red = (unsigned char *)malloc(size);
  green = (unsigned char *)malloc(size);
  blue = (unsigned char *)malloc(size);
  
  if (!red || !green || !blue)
  {
    printf("Insuficient Memory.\n");
    return 0;
  }
  
  printf("Reading...\n");
  
  err = imLoadRGB(ParamStr[1], red, green, blue);
  
  if (err)
  {
    ErrorMsg("Load RGB", err);
    return 0;
  }
  
  pal_size = 256;
  map = (unsigned char *)malloc(size);
  color = (long *)calloc(pal_size, 4);
  
  if (!map || !color)
  {
    printf("Insuficient Memory.\n");
    return 0;
  }
  
  printf("Converting...\n");
  
  imRGB2Map(w, h, red, green, blue, map, pal_size, color);
  
  free(red);
  free(green);
  free(blue);
  
  printf("Writing...\n");
  
  err = imSaveMap(w, h, f, map, pal_size, color, ParamStr[2]);
  
  if (err)
  {
    ErrorMsg("Save Map", err);
    return 0;
  }
  
  free(map);
  free(color);
  
  return 1;
}
